package edu.pku.hawk.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Random;
import java.util.StringTokenizer;

import edu.pku.hawk.controller.util.Constants;
import edu.pku.hawk.controller.util.RegionPoint;
import edu.pku.hawk.controller.util.ReportQueue;
import edu.pku.hawk.controller.util.Util;
import edu.pku.hawk.service.FusionSer;
import edu.pku.hawk.service.bo.FusionResult;
import edu.pku.hawk.service.bo.FusionSensorData;

public class FusionSerImpl_Emulation implements FusionSer {

	private ArrayList<FusionResult> data_i = new ArrayList<FusionResult>();
	private ArrayList<FusionResult> data_m = new ArrayList<FusionResult>();
	private ArrayList<FusionResult> data_p = new ArrayList<FusionResult>();
	private ArrayList<FusionResult> data_mp = new ArrayList<FusionResult>();
	private ArrayList<FusionResult> data_imp = new ArrayList<FusionResult>();

	private int c_i = 0;
	private int c_m = 0;
	private int c_p = 0;
	private int c_mp = 0;
	private int c_imp = 0;

	private int radius_mp_h = 15;
	private int radius_mp_l = 10;

	private int radius_other = 5;

	private long lasttime = System.currentTimeMillis();

	private final long duration = 100;

	public FusionSerImpl_Emulation() {
		loadEmulationData();
	}

	private void loadEmulationData() {
		try {
			load("emulation_IMP.txt", data_imp, Constants.TYPE_TRACK, radius_other + 1, radius_other);
			load("emulation_I.txt", data_i, Constants.TYPE_INFRARED_SENSOR, radius_other + 1, radius_other);
			load("emulation_M.txt", data_m, Constants.TYPE_METAL_SENSOR, radius_other + 1, radius_other);
			load("emulation_P.txt", data_p, Constants.TYPE_PRESSURE_SENSOR, radius_other + 1, radius_other);
			load("emulation_MP.txt", data_mp, Constants.TYPE_TRACK, radius_mp_h, radius_mp_l);

		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	private void load(String fileName, ArrayList<FusionResult> al, int sensorType, int radius_h, int radius_l) {
		ArrayList<String> strs = Util.readFileLines(Constants.Config_Folder_Path + fileName);
		Random r = new Random();
		for (String line : strs) {
			if (Util.isBlankOrNull(line.trim())) {
				continue;
			}
			StringTokenizer token = new StringTokenizer(line);
			FusionResult rp = new FusionResult();
			rp.x = (int)(Integer.valueOf(token.nextToken()) * Constants.Battlefield_Radio);
			rp.y = (int)(Integer.valueOf(token.nextToken()) * Constants.Battlefield_Radio);
			rp.radius = r.nextInt(radius_h - radius_l) + radius_l;
			rp.sensorType = sensorType;
			rp.objType = Constants.TYPE_TRACE_TANK;
			al.add(rp);
		}
	}

	public FusionResult fuse(FusionSensorData[] sdes) {

//		long t = System.currentTimeMillis() - lasttime;
//		if (t < duration) {
//			return null;
//
//		} else {
			FusionResult ret = null;
			ArrayList<FusionResult> dal = null;
			int dalc = 0;
			HashSet<Integer> types = new HashSet<Integer>();
			if (sdes != null) {
				for (FusionSensorData fsd : sdes) {
					types.add(Integer.valueOf(fsd.id));
				}
			}
			if (types.size() == 2 && c_mp < data_mp.size()) {
				ret = data_mp.get(c_mp++);
			} else if (types.size() >= 3 && c_imp < data_imp.size()) {
				ret = data_imp.get(c_imp++);
			} else {
				ret = null;
			}

			lasttime = System.currentTimeMillis();
			return ret;
//		}

	}

	public FusionResult fuseSingle(FusionSensorData[] sde) {
//		long t = System.currentTimeMillis() - lasttime;
//		if (t < duration) {
//			return null;
//
//		} else {
			FusionResult ret = null;
			ArrayList<FusionResult> dal = null;
			int dalc = 0;
			if (sde[0].type == Constants.TYPE_INFRARED_SENSOR && c_i < data_i.size()) {
				ret = data_i.get(c_i++);
			} else if (sde[0].type == Constants.TYPE_METAL_SENSOR && c_m < data_m.size()) {
				ret = data_m.get(c_m++);
			} else if (sde[0].type == Constants.TYPE_PRESSURE_SENSOR && c_p < data_p.size()) {
				ret = data_p.get(c_p++);
			}
			
			lasttime = System.currentTimeMillis();
			return ret;
//		}
	}
	
	public FusionResult fuseAll(final HashMap<Integer, ReportQueue> map) {
		return null;
	}
	
	public void resetCount() {
		c_i = 0;
		c_m = 0;
		c_p = 0;
		c_mp = 0;
		c_imp = 0;
	}

}
